package com.charlotte.study.gupao.state.order;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.persist.DefaultStateMachinePersister;
import org.springframework.statemachine.support.DefaultStateMachineContext;

import java.util.EnumSet;

/**
 * @author junjie.ding
 * @date 2020/3/23
 */
@Configuration
@EnableStateMachine(name = "orderStateMachine")
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderStatus, OrderStatusChangeEvent> {

    /**
     * 配置状态，起始状态
     * @param states
     * @throws Exception
     */
    @Override
    public void configure(StateMachineStateConfigurer<OrderStatus, OrderStatusChangeEvent> states) throws Exception {

        states.withStates().initial(OrderStatus.WAIT_PAY).states(EnumSet.allOf(OrderStatus.class));
    }


    /**
     * 配置状态转换事件关系
     * @param transitions
     * @throws Exception
     */
    @Override
    public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderStatusChangeEvent> transitions) throws Exception {
        transitions
                // 等待付款 ---> 等待发货 由付款动作触发
                .withExternal().source(OrderStatus.WAIT_PAY).target(OrderStatus.WAIT_DELIVER).event(OrderStatusChangeEvent.PAY)
                .and()
                // 等待发货 ---> 等待确认收货 由发货动作触发
                .withExternal().source(OrderStatus.WAIT_DELIVER).target(OrderStatus.WAIR_RECEIVE).event(OrderStatusChangeEvent.DELIEVER)
                .and()
                // 等待确认收货 ---> 订单完成 由确认收货动作触发
                .withExternal().source(OrderStatus.WAIR_RECEIVE).target(OrderStatus.FINISH).event(OrderStatusChangeEvent.RECEIVED);
    }


    /**
     * 持久化配置
     * @return
     */
    @Bean
    public DefaultStateMachinePersister persister(){
        return new DefaultStateMachinePersister<>(new StateMachinePersist<Object, Object, Order>() {

            @Override
            public void write(StateMachineContext<Object, Object> stateMachineContext, Order order) throws Exception {
                // 可进行持久化操作
            }

            @Override
            public StateMachineContext<Object, Object> read(Order order) throws Exception {
                // 可以从持久化层返回数据
                return new DefaultStateMachineContext<>(order.getOrderStatus(), null, null, null);
            }
        });
    }

}
